﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public class ActivosInformeFactory
    {
        //Método que saca los activos actuales de una empresa y los inserta en su tabla de Informe
        public static bool InsertaActivosInforme(int IdEmpresa, int IdInforme)
        {
            //Valor de la ejecucion si todo va bien
            bool ok = true;
            ModeloContainer agenteBD = new ModeloContainer();
            List<ActivosEmpresa> ActivosEmp = (from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                               join Emp in agenteBD.EmpresasEstablecer on ActEmp.IdEmpresa equals Emp.IdEmpresa
                                               where Emp.IdEmpresa == IdEmpresa && ActEmp.Actual == true
                                               select ActEmp).ToList();
            if (ActivosEmp.Count == 0)
            {
                //No se recogieron controles se devuelve un valor de error
                ok = false;
                return ok;
            }
            else
            {
                foreach (ActivosEmpresa ActivoEmp in ActivosEmp)
                {
                    ActivosInforme nuevoControlEmpInf = new ActivosInforme();
                    nuevoControlEmpInf.IdInforme = IdInforme;
                    nuevoControlEmpInf.IdActivo = ActivoEmp.IdActivo;
                    nuevoControlEmpInf.ValorEstrategicoInforme = ActivoEmp.ValorEstrategico;
                    nuevoControlEmpInf.CosteActivoInforme = ActivoEmp.CosteActivo;
                    agenteBD.AddToActivosInformeEstablecer(nuevoControlEmpInf);
                }
                agenteBD.SaveChanges();
                return ok;
            }
        }

        //Método que devuelve el número de activos actuales de un informe
        public static int NumeroTotalesActivosEmpresaInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NTipActivoEmp = (from ActInf in agenteBD.ActivosInformeEstablecer
                                 where ActInf.IdInforme == IdInforme
                                 select ActInf).Distinct().Count();
            return NTipActivoEmp;
        }

        //Método que recoge el número de activos de un tipo de activo para un informe dado
        internal static int NumeroActivosTipoActivoInforme(int IdInforme, int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NTipActivoEmp = (from ActInf in agenteBD.ActivosInformeEstablecer
                                 join ActEmp in agenteBD.ActivosEmpresaEstablecer on ActInf.IdActivo equals ActEmp.IdActivo
                                 where ActEmp.IdTipoActivo == IdTipoActivo &&
                                       ActInf.IdInforme == IdInforme
                                 select ActInf).Count();
            return NTipActivoEmp;
        }

        //Recoge el número de activos  de un Informe por cada tipo de Valor estratégico 
        public static List<int> ActivosInformePorValor(int IdInforme)
        {
            List<int> LActivosValor = new List<int>();
            ModeloContainer agenteBD = new ModeloContainer();
            int NumeroValores = 3;
            for (int i = 0; i < NumeroValores; i++)
            {
                //Los valores posibles de Valor Activo van del 1 al 3 por eso llamamos con el contador i aumentado en 1
                int ValorActivo = i + 1;
                int NumActValor = NumActivosInformeValor(IdInforme, ValorActivo);
                LActivosValor.Insert(i, NumActValor);
            }
            return LActivosValor;
        }

        //Recoge el número de activos por dado un informe y valor estratégico del activo
        public static int NumActivosInformeValor(int IdInforme, int ValorActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int ActivosValor = (from ActInf in agenteBD.ActivosInformeEstablecer
                                where ActInf.ValorEstrategicoInforme == ValorActivo && ActInf.IdInforme == IdInforme
                                select ActInf).Count();
            return ActivosValor;
        }

        //Recoge la lista de Activos para cada uno de los rangos introducido en la lista de rangos
        public static List<int> ActivosInformePorCoste(int IdInforme, List<int> Rangos)
        {
            List<int> ListaActivosValor = new List<int>();
            ModeloContainer agenteBD = new ModeloContainer();
            int nuevoRango = 0, viejoRango = 0;
            for (int i = 0; i < Rangos.Count && Rangos[i] != 0; i++)
            {
                int ActivosCosteRango = -1;
                //Si estamos en el primer rango, no existe rango anterior
                if (i == 0)
                {
                    nuevoRango = Rangos[i];
                    ActivosCosteRango = (from ActInf in agenteBD.ActivosInformeEstablecer
                                         where ActInf.CosteActivoInforme <= nuevoRango && ActInf.CosteActivoInforme > 0 &&
                                                ActInf.IdInforme == IdInforme
                                         select ActInf).Count();
                }
                //Si estamos en el último son todos los activos mayores que el rango
                else if (i == (Rangos.Count - 1))
                {
                    ActivosCosteRango = (from ActInf in agenteBD.ActivosInformeEstablecer
                                         where ActInf.CosteActivoInforme > nuevoRango &&
                                                ActInf.IdInforme == IdInforme
                                         select ActInf).Count();
                }
                //Si no, estamos tenemos un rango inferior y otro superior
                else
                {
                    viejoRango = Rangos[i - 1];
                    nuevoRango = Rangos[i];
                    ActivosCosteRango = (from ActInf in agenteBD.ActivosInformeEstablecer
                                         where ActInf.CosteActivoInforme <= nuevoRango &&
                                                ActInf.CosteActivoInforme > viejoRango &&
                                                ActInf.IdInforme == IdInforme
                                         select ActInf).Count();
                }
                //Algo ha fallado, devolvemos null
                if (ActivosCosteRango == -1)
                {
                    return new List<int>();
                }
                ListaActivosValor.Insert(i, ActivosCosteRango);
            }

            return ListaActivosValor;
        }

        //Método que elimina de forma permanente, todos los activos de informe asociados a una empresa
        internal static void EliminaTotalActivosInforme(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosInforme> ActivosEliminarQuery = from ActInf in agenteBD.ActivosInformeEstablecer
                                                              join EmpInf in agenteBD.EmpresaInformeEstablecer on ActInf.IdInforme equals EmpInf.IdInforme
                                                              where EmpInf.IdEmpresa == IdEmpresa
                                                              select ActInf;
            if (ActivosEliminarQuery.Count() != 0)
            {
                foreach (ActivosInforme ActivoInforme in ActivosEliminarQuery)
                {
                    agenteBD.ActivosInformeEstablecer.DeleteObject(ActivoInforme);
                }
                agenteBD.SaveChanges();
            }
        }

        //Método que elimina de forma permanente, todos los activos de informe asociados a un informe
        internal static void EliminaActivosInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosInforme> ActivosEliminarQuery = from ActInf in agenteBD.ActivosInformeEstablecer
                                                              where ActInf.IdInforme == IdInforme
                                                              select ActInf;
            if (ActivosEliminarQuery.Count() != 0)
            {
                foreach (ActivosInforme ActivoInforme in ActivosEliminarQuery)
                {
                    agenteBD.ActivosInformeEstablecer.DeleteObject(ActivoInforme);
                }
                agenteBD.SaveChanges();
            }
        }

        /*
        //Método que muestra la evolución de los activos según una lista de informes y los formatea para mostrarlos en una tabla
        public static List<PuntoIntXY> ActivosPorInformesXY(List<int> LInformes)
        {
            List<PuntoIntXY> LPuntos = new List<PuntoIntXY>();
            foreach (int IdInforme in LInformes)
            {
                int NumeroActivosInf = ActivosInformeFactory.NumeroTotalesActivosEmpresaInforme(IdInforme);
                PuntoIntXY numActPunto = new PuntoIntXY(IdInforme.ToString(), NumeroActivosInf, "Total");
                LPuntos.Add(numActPunto);
                int NumActAltoInf = ActivosInformeFactory.NumActivosInformeValor(IdInforme, 3);
                PuntoIntXY numActAltoPunto = new PuntoIntXY(IdInforme.ToString(), NumActAltoInf, "Alto");
                LPuntos.Add(numActAltoPunto);
                int NumActMedioInf = ActivosInformeFactory.NumActivosInformeValor(IdInforme, 2);
                PuntoIntXY numActMedioPunto = new PuntoIntXY(IdInforme.ToString(), NumActMedioInf, "Medio");
                LPuntos.Add(numActMedioPunto);
                int NumActBajoInf = ActivosInformeFactory.NumActivosInformeValor(IdInforme, 1);
                PuntoIntXY numActBajoPunto = new PuntoIntXY(IdInforme.ToString(), NumActBajoInf, "Bajo");
                LPuntos.Add(numActBajoPunto);
            }
            return LPuntos;
        }
         * */
        /*
        //Método que recoge los activos del Informe Base y los muestra en la tabla
        public static List<ActivosEvolucionInforme> ActivosInformeBase(int IdInforme)
        {
            List<ActivosEvolucionInforme> LActivos = new List<ActivosEvolucionInforme>();
            ModeloContainer agenteBD = new ModeloContainer();
            var ActivosEmpresa = from ActInf in agenteBD.ActivosInformeEstablecer
                                 join ActEmp in agenteBD.ActivosEmpresaEstablecer on ActInf.IdActivo equals ActEmp.IdActivo
                                 join TipAct in agenteBD.TiposActivosEstablecer on ActEmp.IdTipoActivo equals TipAct.IdTipoActivo
                                 where ActInf.IdInforme == IdInforme
                                 orderby ActInf.ValorEstrategicoInforme descending, ActInf.CosteActivoInforme descending
                                 select new { ActInf.IdInforme, ActInf.IdActivo, ActEmp.Nombre, TipAct.TipoActivo, ActInf.CosteActivoInforme, ActInf.ValorEstrategicoInforme };
            foreach (var Activo in ActivosEmpresa)
            {
                String ValorEstrategico = ActivosEmpresaFactory.RecogeValorEstrategico(Activo.ValorEstrategicoInforme);
                ActivosEvolucionInforme NuevoActivo = new ActivosEvolucionInforme();
                NuevoActivo.Id = Activo.IdActivo;
                NuevoActivo.IdInforme = Activo.IdInforme;
                NuevoActivo.Nombre = Activo.Nombre;
                NuevoActivo.TipoActivo = Activo.TipoActivo;
                NuevoActivo.Coste = Activo.CosteActivoInforme;
                NuevoActivo.ValorEstrategico = ValorEstrategico;
                LActivos.Add(NuevoActivo);
            }
            return LActivos;
        }
         * */

        /*
        //Devuelve para formatear en una tabla los activos que se han eliminado en una lista de informes, a partir
        //de un informe base
        public static List<ActivosEvolucionInforme> ActivosEvolucionEliminados(List<int> LInformes)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            LInformes.Sort();
            List<ActivosEvolucionInforme> LActivosDatInfElim = new List<ActivosEvolucionInforme>();
            //Recogemos los Activos del Informe Base
            for (int i = 0; i < LInformes.Count(); i++)
            {
                int IdInformeBase = LInformes[i];
                List<ActivosInforme> LActivosEliminados = new List<ActivosInforme>();
                IQueryable<int> ActivosInformeBase = from ActInf in agenteBD.ActivosInformeEstablecer
                                                     where ActInf.IdInforme == IdInformeBase
                                                     select ActInf.IdActivo;
                //Pasamos por cada Activo viendo sus activos y comparándolos con los ActivosBase
                for (int j = (i + 1); j < (LInformes.Count); j++)
                {
                    int IdInformeActual = LInformes[j];
                    IQueryable<int> ActivosInformeActual = from ActInf in agenteBD.ActivosInformeEstablecer
                                                           where ActInf.IdInforme == IdInformeActual
                                                           select ActInf.IdActivo;
                    //Sacamos los activos Eliminados del informe base al Informe Actual
                    IQueryable<int> ActivosEliminadosQuery = ActivosInformeBase.Except(ActivosInformeActual);
                    //Recorremos los activos eliminados y los añadimos a la lista si no habían sido añadidos anteriormente
                    foreach (int IdAct in ActivosEliminadosQuery)
                    {
                        ActivosInforme Act = (from ActInf in agenteBD.ActivosInformeEstablecer
                                              where ActInf.IdActivo == IdAct && ActInf.IdInforme == IdInformeBase
                                              select ActInf).Single();
                        bool nuevoActivo = true;
                        for (int k = 0; k < LActivosDatInfElim.Count(); k++)
                        {
                            if (LActivosDatInfElim[k].Id == Act.IdActivo)
                            {
                                nuevoActivo = false;
                            }
                        }
                        if (nuevoActivo)
                        {
                            ActivosEvolucionInforme ActivoEliminado = new ActivosEvolucionInforme();
                            ActivoEliminado.Id = Act.IdActivo;
                            ActivoEliminado.IdInformeBase = IdInformeBase;
                            ActivoEliminado.IdInforme = IdInformeActual;
                            ActivoEliminado.Nombre = ActivosInformeFactory.NombreActivoInforme(Act.IdActivo);
                            ActivoEliminado.TipoActivo = ActivosInformeFactory.TipoActivoActivoInforme(Act.IdActivo);
                            ActivoEliminado.Coste = Act.CosteActivoInforme;
                            String ValorEstrategico = ActivosEmpresaFactory.RecogeValorEstrategico(Act.ValorEstrategicoInforme);
                            ActivoEliminado.ValorEstrategico = ValorEstrategico;
                            LActivosDatInfElim.Add(ActivoEliminado);
                        }
                    }
                }
            }
            return LActivosDatInfElim;
        }
         * */

        //Devuelve el Tipo de Activo de un Activo de un Informe
        public static string TipoActivoActivoInforme(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NTipoActivo = from Act in agenteBD.ActivosEmpresaEstablecer
                                             join TipAct in agenteBD.TiposActivosEstablecer on Act.IdTipoActivo equals TipAct.IdTipoActivo
                                             where Act.IdActivo == IdActivo
                                             select TipAct.TipoActivo;
            if (NTipoActivo.Count() == 0)
                return "";
            else
                return NTipoActivo.First();
        }

        //Método que recoge el nombre de un activo de un informe
        public static string NombreActivoInforme(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NActivo = from Act in agenteBD.ActivosEmpresaEstablecer
                                         where Act.IdActivo == IdActivo
                                         select Act.Nombre;
            if (NActivo.Count() == 0)
                return "";
            else
                return NActivo.First();
        }

        /*
        //Devuelve para formatear en una tabla los activos que se han ido añadiendo en la lista de informes, a partir
        //de un informe base
        public static List<ActivosEvolucionInforme> ActivosEvolucionNuevos(List<int> LInformes)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            LInformes.Sort();
            List<ActivosEvolucionInforme> LActivosDatInfNuevos = new List<ActivosEvolucionInforme>();
            //Recogemos los Activos del Informe Base
            for (int i = 0; i < LInformes.Count(); i++)
            {
                int IdInformeBase = LInformes[i];
                List<ActivosInforme> LActivosEliminados = new List<ActivosInforme>();
                IQueryable<int> ActivosInformeBase = from ActInf in agenteBD.ActivosInformeEstablecer
                                                     where ActInf.IdInforme == IdInformeBase
                                                     select ActInf.IdActivo;
                //Pasamos por cada Activo viendo sus activos y comparándolos con los ActivosBase
                for (int j = (i + 1); j < (LInformes.Count); j++)
                {
                    int IdInformeActual = LInformes[j];
                    IQueryable<int> ActivosInformeActual = from ActInf in agenteBD.ActivosInformeEstablecer
                                                           where ActInf.IdInforme == IdInformeActual
                                                           select ActInf.IdActivo;
                    //Sacamos los activos añadidos del informe base al Informe Actual
                    IQueryable<int> ActivosNuevosQuery = ActivosInformeActual.Except(ActivosInformeBase);
                    //Recorremos los activos nuevos y los añadimos a la lista si no habían sido añadidos anteriormente
                    foreach (int IdAct in ActivosNuevosQuery)
                    {
                        ActivosInforme Act = (from ActInf in agenteBD.ActivosInformeEstablecer
                                              where ActInf.IdActivo == IdAct && ActInf.IdInforme == IdInformeActual
                                              select ActInf).Single();
                        bool nuevoActivo = true;
                        for (int k = 0; k < LActivosDatInfNuevos.Count(); k++)
                        {
                            if (LActivosDatInfNuevos[k].Id == Act.IdActivo)
                            {
                                nuevoActivo = false;
                            }
                        }
                        if (nuevoActivo)
                        {
                            ActivosEvolucionInforme ActivoNuevo = new ActivosEvolucionInforme();
                            ActivoNuevo.Id = Act.IdActivo;
                            ActivoNuevo.IdInformeBase = IdInformeBase;
                            ActivoNuevo.IdInforme = IdInformeActual;
                            ActivoNuevo.Nombre = ActivosInformeFactory.NombreActivoInforme(Act.IdActivo);
                            ActivoNuevo.TipoActivo = ActivosInformeFactory.TipoActivoActivoInforme(Act.IdActivo);
                            ActivoNuevo.Coste = Act.CosteActivoInforme;
                            String ValorEstrategico = ActivosEmpresaFactory.RecogeValorEstrategico(Act.ValorEstrategicoInforme);
                            ActivoNuevo.ValorEstrategico = ValorEstrategico;
                            LActivosDatInfNuevos.Add(ActivoNuevo);
                        }
                    }
                }
            }
            return LActivosDatInfNuevos;
        }
         * */

        internal static void EliminaActivosInformes(List<int> LInformes)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosInforme> ActivosEliminarQuery = from ActInf in agenteBD.ActivosInformeEstablecer
                                                              where LInformes.Contains(ActInf.IdInforme)
                                                              select ActInf;
            if (ActivosEliminarQuery.Count() != 0)
            {
                foreach (ActivosInforme ActivoInforme in ActivosEliminarQuery)
                {
                    agenteBD.ActivosInformeEstablecer.DeleteObject(ActivoInforme);
                }
                agenteBD.SaveChanges();
            }
        }
    }
}
